home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / tex / dvi / dvipssrc.zoo / atari / afm2tfm.c next >
C/C++ Source or Header  |  1991-04-27  |  36KB  |  1,296 lines

  1. /*
  2.  *   This program converts AFM files to TeX TFM files, and optionally
  3.  *   to TeX VPL files that retain all kerning and ligature information.
  4.  *   Both files make the characters not normally encoded by TeX available
  5.  *   by character codes greater than 127.
  6.  */
  7.  
  8. /*   (Modified by Don Knuth from Tom Rokicki's pre-VPL version.) */
  9.  
  10. /*   Modified for the Atari ST by Tim Gallivan 4/27/91  */
  11.  
  12. #include <stdio.h>
  13. #ifdef SYSV
  14. #include <string.h>
  15. #else
  16. #ifdef VMS
  17. #include <string.h>
  18. #else
  19. #include <strings.h>
  20. #endif
  21. #endif
  22. #include <math.h>
  23.  
  24. #ifdef MSDOS
  25. #define WRITEBIN "wb"
  26. #else
  27. #ifdef atarist
  28. #define WRITEBIN "wb"
  29. #else
  30. #define WRITEBIN "w"
  31. #endif
  32. #endif
  33.  
  34. char *texencoding[] = {
  35.    "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma",
  36.    "Upsilon", "Phi", "Psi", "Omega", "arrowup", "arrowdown", "quotesingle",
  37.    "exclamdown", "questiondown", "dotlessi", "dotlessj", "grave", "acute",
  38.    "caron", "breve", "macron", "ring", "cedilla", "germandbls", "ae", "oe",
  39.    "oslash", "AE", "OE", "Oslash", "space", "exclam", "quotedbl", "numbersign",
  40.    "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright",
  41.    "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one",
  42.    "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon",
  43.    "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C",
  44.    "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  45.    "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
  46.    "bracketright", "circumflex", "underscore", "quoteleft", "a", "b", "c", "d",
  47.    "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
  48.    "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright",
  49.    "tilde", "dieresis" } ;
  50. /*
  51.  *   The above layout corresponds to TeX Typewriter Type and is compatible
  52.  *   with TeX Text because the position of ligatures is immaterial.
  53.  */
  54.  
  55. /*
  56.  *   This is what we store Adobe data in.
  57.  */
  58. struct adobeinfo {
  59.    struct adobeinfo *next ;
  60.    int adobenum, texnum, width ;
  61.    char *adobename ;
  62.    int llx, lly, urx, ury ;
  63.    struct lig *ligs ;
  64.    struct kern *kerns ;
  65.    struct pcc *pccs ;
  66.    int wptr, hptr, dptr, iptr ;
  67. } *adobechars, *adobeptrs[256], *texptrs[256],
  68.   *uppercase[256], *lowercase[256] ;
  69. struct lig {
  70.    struct lig *next ;
  71.    char *succ, *sub ;
  72. } ;
  73. struct kern {
  74.    struct kern *next ;
  75.    char *succ ;
  76.    int delta ;
  77. } ;
  78. struct pcc {
  79.    struct pcc *next ;
  80.    char * partname ;
  81.    int xoffset, yoffset ;
  82. } ;
  83.  
  84. FILE *afmin, *vplout, *tfmout ;
  85. char inname[200], outname[200] ; /* names of input and output files */
  86. char buffer[255]; /* input buffer (modified while parsing) */
  87. char obuffer[255] ; /* unmodified copy of input buffer */
  88. char *param ; /* current position in input buffer */
  89. char *fontname = "Unknown" ;
  90. char *codingscheme = "Unspecified" ;
  91. float italicangle = 0.0 ;
  92. char fixedpitch ;
  93. char makevpl ;
  94. int xheight = 400 ;
  95. int fontspace ;
  96. int bc, ec ;
  97. long cksum ;
  98. float efactor = 1.0, slant = 0.0 ;
  99. double newslant ;
  100. char titlebuf[100] ;
  101.  
  102. void
  103. error(s)
  104. register char *s ;
  105. {
  106.    extern void exit() ;
  107.  
  108.    (void)fprintf(stderr, "%s\n", s) ;
  109.    if (obuffer[0]) {
  110.       (void)fprintf(stderr, "%s\n", obuffer) ;
  111.       while (param > buffer) {
  112.          (void)fprintf(stderr, " ") ;
  113.          param-- ;
  114.       }
  115.       (void)fprintf(stderr, "^\n") ;
  116.    }
  117.    if (*s == '!')
  118.       exit(1) ;
  119. }
  120.  
  121. int
  122. transform(x,y)
  123.    register int x,y ;
  124. {
  125.    register double acc ;
  126.    acc = efactor * x + slant *y ;
  127.    return (int)(acc>=0? acc+0.5 : acc-0.5 ) ;
  128. }
  129.  
  130. int
  131. getline() {
  132.    register char *p ;
  133.    register int c ;
  134.  
  135.    param = buffer ;
  136.    for (p=buffer; (c=getc(afmin)) != EOF && c != 10;)
  137.       *p++ = c ;
  138.    *p = 0 ;
  139.    (void)strcpy(obuffer, buffer) ;
  140.    if (p == buffer && c == EOF)
  141.       return(0) ;
  142.    else
  143.       return(1) ;
  144. }
  145.  
  146. char *interesting[] = { "FontName", "ItalicAngle", "IsFixedPitch",
  147.    "XHeight", "C", "KPX", "CC", "EncodingScheme", NULL} ; 
  148. #define FontName (0)
  149. #define ItalicAngle (1)
  150. #define IsFixedPitch (2)
  151. #define XHeight (3)
  152. #define C (4)
  153. #define KPX (5)
  154. #define CC (6)
  155. #define EncodingScheme (7)
  156. #define NONE (-1)
  157. int
  158. interest(s)
  159. char *s ;
  160. {
  161.    register char **p ;
  162.    register int n ;
  163.  
  164.    for (p=interesting, n=0; *p; p++, n++)
  165.       if (strcmp(s, *p)==0)
  166.          return(n) ;
  167.    return(NONE) ;
  168. }
  169.  
  170. char *
  171. mymalloc(len)
  172. int len ;
  173. {
  174.    register char *p ;
  175.    extern char *malloc() ;
  176.  
  177.    p = malloc((unsigned)len) ;
  178.    if (p==NULL)
  179.       error("! out of memory") ;
  180.    return(p) ;
  181. }
  182.  
  183. char *
  184. paramnewstring() {
  185.    register char *p, *q ;
  186.  
  187.    p = param ;
  188.    while (*p > ' ')
  189.       p++ ;
  190.    q = mymalloc((int)(p-param+1)) ;
  191.    if (*p != 0)
  192.       *p++ = 0 ;
  193.    (void)strcpy(q, param) ;
  194.    while (*p && *p <= ' ')
  195.       p++ ;
  196.    param = p ;
  197.    return(q) ;
  198. }
  199.  
  200. char *
  201. paramstring() {
  202.    register char *p, *q ;
  203.  
  204.    p = param ;
  205.    while (*p > ' ')
  206.       p++ ;
  207.    q = param ;
  208.    if (*p != 0)
  209.       *p++ = 0 ;
  210.    while (*p && *p <= ' ')
  211.       p++ ;
  212.    param = p ;
  213.    return(q) ;
  214. }
  215.  
  216. int
  217. paramnum() {
  218.    register char *p ;
  219.    int i ;
  220.  
  221.    p = paramstring() ;
  222.    if (sscanf(p, "%d", &i) != 1)
  223.       error("! integer expected") ;
  224.    return(i) ;
  225. }
  226.  
  227. float
  228. paramfloat() {
  229.    register char *p ;
  230.    float i ;
  231.  
  232.    p = paramstring() ;
  233.    if (sscanf(p, "%f", &i) != 1)
  234.       error("! number expected") ;
  235.    return(i) ;
  236. }
  237.  
  238. struct adobeinfo *
  239. newchar() {
  240.    register struct adobeinfo *ai ;
  241.  
  242.    ai = (struct adobeinfo *)mymalloc(sizeof(struct adobeinfo)) ;
  243.    ai->adobenum = -1 ;
  244.    ai->texnum = -1 ;
  245.    ai->width = -1 ;
  246.    ai->adobename = NULL ;
  247.    ai->llx = -1 ;
  248.    ai->lly = -1 ;
  249.    ai->urx = -1 ;
  250.    ai->ury = -1 ;
  251.    ai->ligs = NULL ;
  252.    ai->kerns = NULL ;
  253.    ai->pccs = NULL ;
  254.    ai->next = adobechars ;
  255.    adobechars = ai ;
  256.    return(ai) ;
  257. }
  258.  
  259. struct kern *
  260. newkern() {
  261.    register struct kern *nk ;
  262.  
  263.    nk = (struct kern *)mymalloc(sizeof(struct kern)) ;
  264.    nk->next = NULL ;
  265.    nk->succ = NULL ;
  266.    nk->delta = 0 ;
  267.    return(nk) ;
  268. }
  269.  
  270. struct pcc *
  271. newpcc() {
  272.    register struct pcc *np ;
  273.  
  274.    np = (struct pcc *)mymalloc(sizeof(struct pcc)) ;
  275.    np->next = NULL ;
  276.    np->partname = NULL ;
  277.    np->xoffset = 0 ;
  278.    np->yoffset = 0 ;
  279.    return(np) ;
  280. }
  281.  
  282. struct lig *
  283. newlig() {
  284.    register struct lig *nl ;
  285.  
  286.    nl = (struct lig *)mymalloc(sizeof(struct lig)) ;
  287.    nl->next = NULL ;
  288.    nl->succ = NULL ;
  289.    nl->sub = NULL ;
  290.    return(nl) ;
  291. }
  292.  
  293. void
  294. expect(s)
  295. char *s ;
  296. {
  297.    if (strcmp(paramstring(), s) != 0) {
  298.       (void)fprintf(stderr, "%s expected: ", s) ;
  299.       error("! syntax error") ;
  300.    }
  301. }
  302.  
  303. void
  304. handlechar() { /* an input line beginning with C */
  305.    register struct adobeinfo *ai ;
  306.    register struct lig *nl ;
  307.  
  308.    ai = newchar() ;
  309.    ai->adobenum = paramnum() ;
  310.    expect(";") ;
  311.    expect("WX") ;
  312.    ai->width = transform(paramnum(),0) ;
  313.    if (ai->adobenum >= 0 && ai->adobenum < 256) {
  314.       adobeptrs[ai->adobenum] = ai ;
  315.       cksum = (cksum<<1) ^ ai->width ;
  316.    }
  317.    expect(";") ;
  318.    expect("N") ;
  319.    ai->adobename = paramnewstring() ;
  320.    expect(";") ;
  321.    expect("B") ;
  322.    ai->llx = paramnum() ;
  323.    ai->lly = paramnum() ;
  324.    ai->llx = transform(ai->llx, ai->lly) ;
  325.    ai->urx = paramnum() ;
  326.    ai->ury = paramnum() ;
  327.    ai->urx = transform(ai->urx, ai->ury) ;
  328. /* We need to avoid negative heights or depths. They break accents in
  329.    math mode, among other things.  */
  330.    if (ai->lly > 0)
  331.       ai->lly = 0 ;
  332.    if (ai->ury < 0)
  333.       ai->ury = 0 ;
  334.    expect(";") ;
  335. /* Now look for ligatures (which aren't present in fixedpitch fonts) */
  336.    while (*param == 'L') {
  337.       expect("L") ;
  338.       nl = newlig() ;
  339.       nl->succ = paramnewstring() ;
  340.       nl->sub = paramnewstring() ;
  341.       nl->next = ai->ligs ;
  342.       ai->ligs = nl ;
  343.       expect(";") ;
  344.    }
  345.    if (strcmp(ai->adobename, "space")==0) {
  346.       fontspace = ai->width ;
  347.       nl = newlig() ;        /* space will act as zero-width Polish crossbar */
  348.       nl->succ = "l" ;       /* when used by plain TeX'